package org.iteam.core.strtus2.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.iteam.commons.json.JSONObject;
import org.iteam.core.Constant;
import org.iteam.core.shiro.AuthUtils;

public class AuthFilter implements Filter {

	private static String[] urls = {};
	private static String[] jsons = {};
	private static String errorMsg = "拒绝访问，没有权限";

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		String url = substring(request.getServletPath(), 1);
		if (validate(url)) {
			url = url.replaceAll("/", ":");
			Subject subject = SecurityUtils.getSubject();
			int validate = AuthUtils.validate(url);
			switch (validate) {
			// -2:禁止访问
			case -2:
				write(request, response, url, errorMsg);
				break;
			// -1: 不要验证
			case -1:
				chain.doFilter(request, response);
				break;
			// 0:需要验证允许通过
			case 0:
				if (subject.isAuthenticated())
					if (subject.isPermitted(url) || AuthUtils.isPermission(url))
						chain.doFilter(request, response);
					else
						write(request, response, url, errorMsg);
				else
					write(request, response, url, "用户登录过期，请重新登录");
				break;
			// 1:需要验证禁止通过
			case 1:
				if (!subject.isPermitted(url) && !AuthUtils.isPermission(url))
					chain.doFilter(request, response);
				else
					write(request, response, url, errorMsg);
				break;
			// 2:只验证是否登录SecurityUtils
			case 2:
				if (subject.isAuthenticated())
					chain.doFilter(request, response);
				else
					write(request, response, url, errorMsg);
				break;
			default:
				write(request, response, url, errorMsg);
				break;
			}
		} else
			chain.doFilter(request, response);
	}

	private boolean isPost(String url) {
		for (String json : jsons) {
			if (url.trim().endsWith(json.trim())) {
				return true;
			}
		}
		return false;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void write(HttpServletRequest request,
			HttpServletResponse response, String url, String msg) {
		PrintWriter out = null;
		response.setCharacterEncoding("UTF-8");
		if (!isPost(url)) {
			try {
				out = response.getWriter();
			} catch (IOException e) {
				e.printStackTrace();
			}
			out.print("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><link Rel=\"shortcut icon\" href=\""
					+ request.getContextPath() + "/favicon.ico\"></head>");
			out.println("<title>系统提示");
			out.println("</title>");
			out.println("<body>");
			out.println(msg);
			out.println("</body>");
			out.println("</html>");
		} else {
			Map map = new HashMap();
			map.put("state", false);
			map.put("info", msg);
			response.setContentType("application/json;charset=UTF-8");
			try {
				out = response.getWriter();
				if (url.endsWith("query"))
					out.println(msg);
				else
					out.println(JSONObject.valueToString(map));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		out.close();
	}

	private boolean validate(String url) {
		for (String u : urls) {
			if (u.indexOf("/*") > 0) {
				if (url.startsWith(u.replace("/*", "")))
					return false;
			} else {
				if (url.equals(u))
					return false;
			}
		}
		return true;
	}

	private String substring(String str, int number) {
		for (int i = 0; i < number; i++) {
			str = str.substring(str.indexOf("/") + 1);
		}
		return str;
	}

	@Override
	public void init(FilterConfig cfg) throws ServletException {
		String database = cfg.getInitParameter("database");
		Constant.dataBaseType = Constant.DataBaseType.valueOf(database);
		String url = cfg.getInitParameter("urls");
		if (url != null && !"".equals(url))
			urls = url.split(",");
		String json = cfg.getInitParameter("json");
		if (json != null && !"".equals(json))
			jsons = json.split(",");
		String msg = cfg.getInitParameter("errorMsg");
		if (msg != null && !"".equals(msg))
			errorMsg = msg;
	}
	
	public static void main(String[] args) {
		System.out.println( Constant.DataBaseType.valueOf("MYSQL"));
	}

}
